package com.ys.web.user.friends.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ys.base.BaseConstants;
import com.ys.base.EnumType;
import com.ys.utils.base.http.McodeHandler;
import com.ys.utils.base.j2se.DateUtil;
import com.ys.utils.base.j2se.JsonUtil;
import com.ys.utils.base.j2se.StringHandler;
import com.ys.utils.datasource.DynamicDataSourceContextHolder;
import com.ys.utils.help.GroupUtils;
import com.ys.utils.help.UserUtils;
import com.ys.utils.redis.Redis;
import com.ys.utils.redis.key.UserKey;
import com.ys.utils.spring.config.SystemError;
import com.ys.web.user.friends.dto.FriendsRemarkDTO;
import com.ys.web.user.friends.manager.FriendsManager;
import com.ys.web.user.friends.mapper.UserApplyMapper;
import com.ys.web.user.friends.mapper.UserFriendsMapper;
import com.ys.web.user.friends.mapper.UserGroupMapper;
import com.ys.web.user.friends.mapper.UserWxMapper;
import com.ys.web.user.friends.po.*;
import com.ys.web.user.friends.service.FriendsService;
import com.ys.web.user.login.LoginInfo;
import com.ys.web.user.login.LoginService;
import com.ys.web.user.privacy.PrivacyManager;
import com.ys.web.ws.bean.MessageResponseBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName FriendsServiceImpl
 * @Description 好友接口实现类
 * @Author qxj
 * @Date 2021/5/9 9:46
 * @Version 1.0
 */
@Slf4j
@Service
public class FriendsServiceImpl implements FriendsService {

    @Autowired
    private UserFriendsMapper userFriendsMapper;

    @Autowired
    private UserWxMapper userWxMapper;

    @Autowired
    private UserApplyMapper userApplyMapper;

    @Autowired
    private LoginService loginService;

    @Autowired
    private UserGroupMapper userGroupMapper;

    @Override
    public void refreshAll() {
        List<BaseUserWxPO> baseUserWxPOS = userWxMapper.selectAll();
        baseUserWxPOS.stream().filter(x-> StringHandler.isNotEmpty(x.getPhone())).filter(x->!x.getPhone().contains("已注销")).forEach(x->{
            System.out.println(x.getPhone());
            this.refreshFriend(x.getPhone());
        });
    }

    @Override
    public void refreshFriend(String phone) {
        BaseUserWxPO obj = userWxMapper.selectByPhone(phone);

        if(StringHandler.isNotEmpty(obj) && StringHandler.isNotEmpty(obj.getId())){
            String key = UserKey.getUserFriendsListKey(obj.getId());
            List<BaseUserFriendsPO> friendsList = userFriendsMapper.getFriendsListByUserId(obj.getId());
            if (StringHandler.isNotEmpty(friendsList) && !friendsList.isEmpty()) {
                //保存缓存
                Map<String, String> collect = friendsList
                        .stream()
                        .collect(Collectors.toMap(BaseUserFriendsPO::getFriendId, JsonUtil::toJson));
                Redis.hash.hmset(key, collect);
                Redis.key.setKeyTimeout(key, BaseConstants.SAVE_TIME);
            }
        }else{
            System.err.println(JsonUtil.toJson(obj));
        }
    }

    @Override
    public BaseUserWxPO queryFriendsByPhone(String key) {
        return userFriendsMapper.queryFriendsByPhone(key);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addFriendsById(String uid, String friendId, int groupId, String remark) {
        //验证好友是否存在
        BaseUserWxPO friendsObj = userWxMapper.selectByPrimaryKey(friendId);
        if (StringHandler.isEmpty(friendsObj)) {
            SystemError.wrapBs("500", "好友不存在");
        }
        if (groupId > 0 && PrivacyManager.hideGroup(friendId)) {
            SystemError.wrapBs("500", "对方禁止通过群聊添加好友");
        }
        if (FriendsManager.isBlackFriend(friendId, StringHandler.getLong(uid)) == 1) {
            SystemError.wrapBs("500", "对方禁止添加好友");
        }

        //验证是否是好友关系  已经是好友关系了  就不能再添加
        BaseUserFriendsPO queryObj = new BaseUserFriendsPO();
        queryObj.setUserId(uid);
        queryObj.setFriendId(friendId);
        queryObj.setStatus(true);
        BaseUserFriendsPO friends = userFriendsMapper.selectOne(queryObj);
        if (StringHandler.isNotEmpty(friends)) {
            SystemError.wrapBs("500", "不能重复添加");
            //如果说用户已经添加过一次了 重新添加
//            userFriendsMapper.delete(friends);
//            Redis.hash.delHash(UserKey.getUserApplyKey(friendId),uid);
        }

        BaseUserApplyPO obj = new BaseUserApplyPO();
        obj.setFriendId(uid);
        obj.setUserId(friendId);
        BaseUserApplyPO old = userApplyMapper.selectOne(obj);

        BaseUserApplyPO friendObj = new BaseUserApplyPO();
        friendObj.setFriendId(friendId);
        friendObj.setUserId(uid);
        BaseUserApplyPO friendOld = userApplyMapper.selectOne(friendObj);
        //如果对方添加了我为好友  则直接同意
        if (StringHandler.isNotEmpty(friendOld) && !friendOld.getIsDeal()) {
            if (agreeApply(uid, friendId) == 0) {
                SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), EnumType.ResponseCode.Fail.getDesc());
            }
            friendOld.setAvatarUrl(UserUtils.getCacheUser(friendId).getAvatarUrl());
            friendOld.setNickName(UserUtils.getCacheUser(friendId).getNickName());
            friendOld.setRemark(remark);
            friendOld.setIsDeal(true);
            friendOld.setCreateTime(null);
            friendOld.setUpdateTime(null);
            Redis.hash.hSet(UserKey.getUserApplyKey(friendOld.getUserId()), friendOld.getFriendId(), JsonUtil.toJson(friendOld), BaseConstants.FriendsConstants.SAVE_TIME_APPLY);
            MessageResponseBean messageResponseBean = UserUtils.getMessageResponse(friendId, null, EnumType.MessageCode.MESSAGE_FRIEND_NO_APPLY_AGREE.getCode(), null, null, 0.0, 0.0);
            GroupUtils.sendIfAbsent(messageResponseBean, uid, null);
            return;
        }

        //如果用户添加好友不需要验证
        if (!PrivacyManager.friendVerify(friendId)) {
            //如果有申请，则修改为已处理
            if (StringHandler.isNotEmpty(old) && !old.getIsDeal()) {
                old.setCreateTime(LocalDateTime.now());
                old.setIsDeal(true);
                old.setRemark(remark);
                userApplyMapper.updateByPrimaryKeySelective(obj);
            } else {
                old = new BaseUserApplyPO();
                old.setFriendId(uid);
                old.setUserId(friendId);
                old.setCreateTime(LocalDateTime.now());
                old.setIsDeal(false);
                old.setRemark(remark);
                userApplyMapper.insertSelective(old);
            }
            if (agreeApply(friendId, uid) == 0) {
                SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), EnumType.ResponseCode.Fail.getDesc());
            }
            old.setAvatarUrl(UserUtils.getCacheUser(uid).getAvatarUrl());
            old.setNickName(UserUtils.getCacheUser(uid).getNickName());
            old.setIsDeal(true);
            old.setCreateTime(null);
            old.setUpdateTime(null);
            Redis.hash.hSet(UserKey.getUserApplyKey(old.getUserId()), old.getFriendId(), JsonUtil.toJson(old), BaseConstants.FriendsConstants.SAVE_TIME_APPLY);
            MessageResponseBean messageResponseBean = UserUtils.getMessageResponse(uid, null, EnumType.MessageCode.MESSAGE_FRIEND_NO_APPLY_AGREE.getCode(), null, null, 0.0, 0.0);
            GroupUtils.sendIfAbsent(messageResponseBean, friendId, null);
            return;
        }
        int result = 0;
        //如果之前就存在申请，修改申请为未处理，修改之前对象
        //如果之前不存在申请，创建申请对象进行保存
        if (StringHandler.isNotEmpty(old)) {
            old.setRemark(remark);

            if (old.getIsDeal()) {
                old.setCreateTime(LocalDateTime.now());
                old.setIsDeal(false);
                result = userApplyMapper.updateByPrimaryKeySelective(obj);
                old.setCreateTime(null);
                old.setUpdateTime(null);
            } else {
                //判断好友连接是否存在
                userApplyMapper.updateByPrimaryKeySelective(old);
                LoginInfo cacheUser = UserUtils.getCacheUser(uid);
                old.setAvatarUrl(cacheUser.getAvatarUrl());
                old.setNickName(cacheUser.getNickName());
                old.setIsDeal(StringHandler.isNotEmpty(old.getIsDeal()) ? old.getIsDeal() : false);
                old.setCreateTime(null);
                old.setUpdateTime(null);
                old.setId(StringHandler.isNotEmpty(old.getId()) ? old.getId() : null);
                Redis.hash.hSet(UserKey.getUserApplyKey(old.getUserId()), old.getFriendId(), JSONObject.toJSONString(old), BaseConstants.FriendsConstants.SAVE_TIME_APPLY);
                MessageResponseBean messageResponseBean = UserUtils.getMessageResponse(old.getFriendId(), null, EnumType.MessageCode.MESSAGE_USER_APPLY.getCode(), null, null, 0.0, 0.0);
                GroupUtils.sendIfAbsent(messageResponseBean, friendId, null);
                return;
            }
        } else {
            old = new BaseUserApplyPO();
            old.setFriendId(uid);
            old.setUserId(friendId);
            old.setCreateTime(LocalDateTime.now());
            old.setRemark(remark);
            result = userApplyMapper.insertSelective(old);
            old.setCreateTime(null);
        }
        if (result > 0) {
            LoginInfo cacheUser = UserUtils.getCacheUser(uid);
            old.setAvatarUrl(cacheUser.getAvatarUrl());
            old.setNickName(cacheUser.getNickName());
            old.setIsDeal(StringHandler.isNotEmpty(old.getIsDeal()) ? old.getIsDeal() : false);
            old.setId(StringHandler.isNotEmpty(old.getId()) ? old.getId() : null);
            Redis.hash.hSet(UserKey.getUserApplyKey(old.getUserId()), old.getFriendId(), JSONObject.toJSONString(old), BaseConstants.FriendsConstants.SAVE_TIME_APPLY);
            //判断好友连接是否存在
            MessageResponseBean messageResponseBean = UserUtils.getMessageResponse(old.getFriendId(), null, EnumType.MessageCode.MESSAGE_USER_APPLY.getCode(), null, null, 0.0, 0.0);
            GroupUtils.sendIfAbsent(messageResponseBean, friendId, null);
        } else {
            SystemError.wrapBs("500", "操作失败");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int setFriendsRemarkInfo(String uid, FriendsRemarkDTO friendsRemarkDTO) {
        if (uid.equals(friendsRemarkDTO.getFriendId())) {
            SystemError.wrapBs("500", "操作失败");
        }
        BaseUserFriendsPO queryObj = new BaseUserFriendsPO();
        queryObj.setStatus(true);
        queryObj.setUserId(uid);
        queryObj.setFriendId(friendsRemarkDTO.getFriendId());
        BaseUserFriendsPO obj = userFriendsMapper.selectOne(queryObj);
        if (StringHandler.isNotEmpty(obj)) {
            obj.setFriendRemark(friendsRemarkDTO.getFriendRemark());
            obj.setFriendDesc(friendsRemarkDTO.getFriendDesc());
            obj.setUpdateTime(LocalDateTime.now());
            int result = 0;
            try {
                result = userFriendsMapper.updateByPrimaryKeySelective(obj);
            } catch (UncategorizedSQLException e) {
                SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "名称不合法");
            }
            if (result > 0) {
                //修改缓存中的信息
                String key = UserKey.getUserFriendsListKey(Long.parseLong(uid));
                String field = friendsRemarkDTO.getFriendId();
                String json = (String) Redis.hash.hGet(key, field);
                BaseUserFriendsPO po = JSONObject.parseObject(json, BaseUserFriendsPO.class);
                po.setFriendRemark(friendsRemarkDTO.getFriendRemark());
                po.setFriendDesc(friendsRemarkDTO.getFriendDesc());
                Redis.hash.hSet(key, field, JsonUtil.toJson(po));
            } else {
                SystemError.wrapBs("500", "操作失败");
            }
            return result;
        }
        return 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int delFriendsById(String uid, String friendId) {
        BaseUserFriendsPO queryObj = new BaseUserFriendsPO();
        queryObj.setStatus(true);
        queryObj.setUserId(uid);
        queryObj.setFriendId(friendId);
        BaseUserFriendsPO obj = userFriendsMapper.selectOne(queryObj);
        queryObj.setUserId(friendId);
        queryObj.setFriendId(uid);
        BaseUserFriendsPO other = userFriendsMapper.selectOne(queryObj);
        if (StringHandler.isNotEmpty(obj) && StringHandler.isNotEmpty(other)) {
            obj.setStatus(false);
            obj.setUpdateTime(LocalDateTime.now());
            int result = userFriendsMapper.updateByPrimaryKeySelective(obj);
            other.setStatus(false);
            other.setUpdateTime(LocalDateTime.now());
            int otherResult = userFriendsMapper.updateByPrimaryKeySelective(other);
            if (result > 0 && otherResult > 0) {
//                this.updateRelation(uid, friendId);
//                this.updateRelation(friendId, uid);
                //获取申请对象
                BaseUserApplyPO baseUserApplyPo = userApplyMapper.selectByPrimaryKey(obj.getApplyId());
                //如果说是申请人自己删除的好友  则不保留申请记录
                //如果说是接受人删除   设置请求为未处理
                if (baseUserApplyPo != null) {
//                    if (baseUserApplyPo.getFriendId().equals(uid)) {
                    userApplyMapper.delete(baseUserApplyPo);
                    //删除缓存
                    Redis.hash.delHash(UserKey.getUserApplyKey(baseUserApplyPo.getUserId()),
                            baseUserApplyPo.getFriendId());
//                    } else {
//                        baseUserApplyPo.setIsDeal(false);
//                        baseUserApplyPo.setUpdateTime(LocalDateTime.now());
//                        userApplyMapper.updateByPrimaryKeySelective(baseUserApplyPo);
//                        String str = (String) Redis.hash.hGet(UserKey.getUserApplyKey(baseUserApplyPo.getUserId()), baseUserApplyPo.getFriendId());
//                        BaseUserApplyPO cacheObj = JsonUtil.jsonToBean(str, BaseUserApplyPO.class);
//                        cacheObj.setIsDeal(false);
//                        Redis.hash.hSet(UserKey.getUserApplyKey(baseUserApplyPo.getUserId()), baseUserApplyPo.getFriendId(), JsonUtil.toJson(cacheObj));
//                    }
                }

                //双向删除好友信息从缓存中删除
                Redis.hash.delHash(UserKey.getUserFriendsListKey(uid), friendId);
                Redis.hash.delHash(UserKey.getUserFriendsListKey(friendId), uid);
            } else {
                SystemError.wrapBs("500", "操作失败");
            }
            return result;
        }
        SystemError.wrapBs("6001", "您与对方目前不是好友");
        return 0;
    }

    /**
     * 修改申请对象新消息
     *
     * @param uid
     * @param friendId
     */
    private void updateRelation(String uid, String friendId) {
        //修改好友关联表信息
        BaseUserApplyPO q1 = new BaseUserApplyPO();
        q1.setFriendId(uid);
        q1.setUserId(friendId);
        q1.setIsDeal(true);
        BaseUserApplyPO o1 = userApplyMapper.selectOne(q1);
        if (StringHandler.isNotEmpty(o1)) {
            o1.setIsDeal(false);
            o1.setUpdateTime(LocalDateTime.now());
            userApplyMapper.updateByPrimaryKeySelective(o1);
        }
    }


    @Override
    public BaseUserFriendsPO getFriendsDetailByUserId(String uid, String friendId) {
        //自己查询自己
        if (uid.equals(friendId)) {
            Map map = Redis.hash.hgetall(UserKey.userInfoByUid(uid));
            BaseUserFriendsPO po = new BaseUserFriendsPO();
            po.setUserId(McodeHandler.to32Radix(Long.parseLong(map.get("id").toString())));
            po.setFriendId(McodeHandler.to32Radix(Long.parseLong(map.get("id").toString())));
            po.setNickName(String.valueOf(map.get("nickName")));
            po.setAvatarUrl(String.valueOf(map.get("avatarUrl")));
            po.setGender(Integer.parseInt(String.valueOf(map.get("gender"))));
            return po;
        }
        String key = UserKey.getUserFriendsListKey(uid);
        if (Redis.hash.hasValue(key, friendId)) {
            String jsonStr = (String) Redis.hash.hGet(key, friendId);
            BaseUserFriendsPO baseUserFriendsPo = JSONObject.parseObject(jsonStr, BaseUserFriendsPO.class);
            if (StringHandler.isEmpty(baseUserFriendsPo.getUserId())) {
                SystemError.wrapBs("6001", "您与对方目前不是好友");
            }

            LoginInfo loginInfo = loginService.infoByUid(friendId);
            if(StringHandler.isNotEmpty(loginInfo)) {
                //如果数据不一致   统一数据
                if (!loginInfo.getNickName().equals(baseUserFriendsPo.getNickName()) || !loginInfo.getAvatarUrl().equals(baseUserFriendsPo.getAvatarUrl())) {
                    baseUserFriendsPo.setNickName(loginInfo.getNickName());
                    baseUserFriendsPo.setAvatarUrl(loginInfo.getAvatarUrl());

                    Redis.hash.hSet(key, friendId, JsonUtil.toJson(baseUserFriendsPo));
                }
            }
            baseUserFriendsPo.setUserId(McodeHandler.to32Radix(Long.parseLong(baseUserFriendsPo.getUserId())));
            baseUserFriendsPo.setFriendId(McodeHandler.to32Radix(Long.parseLong(baseUserFriendsPo.getFriendId())));
            return baseUserFriendsPo;
        }
        BaseUserFriendsPO obj = userFriendsMapper.getFriendsDetailByUserId(uid, friendId);
        if (StringHandler.isEmpty(obj)) {
            //防止缓存穿透
            Redis.hash.hSet(key, friendId, JsonUtil.toJson(new BaseUserFriendsPO()));
            return null;
        }
        //好友信息添加进缓存
        Redis.hash.hSet(key, obj.getFriendId(), JsonUtil.toJson(obj));
        //删除没有好友列表的标志
        if (StringHandler.isNotEmpty(Redis.str.get(UserKey.getNoListFlag(obj.getUserId())))) {
            Redis.key.del(UserKey.getNoListFlag(obj.getUserId()));
        }
        obj.setUserId(McodeHandler.to32Radix(Long.parseLong(obj.getUserId())));
        obj.setFriendId(McodeHandler.to32Radix(Long.parseLong(obj.getFriendId())));
        return obj;
    }

    @Override
    public List<BaseUserFriendsPO> getFriendsList(String uid, String searchKey) {
        String key = UserKey.getUserFriendsListKey(uid);
        //查看没有好友列表的标志
        String flag = Redis.str.get(UserKey.getNoListFlag(uid));
        if (StringHandler.isNotEmpty(flag)) {
            return new ArrayList<>();
        }
        Map result = Redis.hash.hgetall(key);
        List<BaseUserFriendsPO> friendsList = new ArrayList<>();
        if (StringHandler.isNotEmpty(result)) {
            List<String> arrayList = new ArrayList<String>(result.values());
            if (StringHandler.isNotEmpty(arrayList)) {
                Redis.key.setKeyTimeout(key, BaseConstants.SAVE_TIME);
                List<BaseUserFriendsPO> list = arrayList
                        .stream()
                        .map(s -> {
                            BaseUserFriendsPO object = JSONObject.parseObject(s, BaseUserFriendsPO.class);
                            if (object != null && object.getId() != null) {
                                object.setUserId(McodeHandler.to32Radix(Long.parseLong(object.getUserId())));
                                object.setFriendId(McodeHandler.to32Radix(Long.parseLong(object.getFriendId())));
                            }
                            return object;
                        })
                        .collect(Collectors.toList());
                friendsList = list.stream().filter(o -> o != null && o.getId() != null).collect(Collectors.toList());
                if (StringHandler.isNotEmpty(searchKey)) {
                    if (StringHandler.isNotEmpty(friendsList) && friendsList.size() > 0) {
                        friendsList = friendsList
                                .stream()
                                .filter(o -> StringHandler.isNotEmpty(o) && StringHandler.isNotEmpty(o.getUserId()) && !"null".equals(o.getUserId()))
                                .filter(o -> (StringHandler.isNotEmpty(o.getNickName()) && o.getNickName().contains(searchKey)) || (StringHandler.isNotEmpty(o.getFriendRemark()) && o.getFriendRemark().contains(searchKey)))
                                .collect(Collectors.toList());
                    }
                }
            }
        } else {
            //数据库查询集合
            friendsList = userFriendsMapper.getFriendsListByUserId(uid);
            if (StringHandler.isNotEmpty(friendsList) && friendsList.size()>0) {
                //保存缓存
                Map<String, String> collect = friendsList
                        .stream()
                        .collect(Collectors.toMap(BaseUserFriendsPO::getFriendId, JsonUtil::toJson));
                Redis.hash.hmset(key, collect);
                Redis.key.setKeyTimeout(key, BaseConstants.SAVE_TIME);
                friendsList.forEach(o -> {
                    o.setUserId(McodeHandler.to32Radix(Long.parseLong(o.getUserId())));
                    o.setFriendId(McodeHandler.to32Radix(Long.parseLong(o.getFriendId())));
                });
            }

            //在缓存中存一个 hash 的key  防止用户一直刷新访问数据库
            if (StringHandler.isEmpty(friendsList)) {
                Redis.str.set(UserKey.getNoListFlag(uid), "1", 30 * 10);
            }
        }
        if (StringHandler.isNotEmpty(friendsList) && friendsList.size() > 0) {
            //黑名单判断
            return friendsList.stream()
                    .peek(x -> x.setIsHidden(FriendsManager.isBlackFriend(StringHandler.getString(McodeHandler.from32Radix(x.getUserId())), McodeHandler.from32Radix(x.getFriendId())))).collect(Collectors.toList());

        } else {
            return new ArrayList<>();
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int agreeApply(String uid, String fromId) {
        BaseUserApplyPO userApplyPO = new BaseUserApplyPO();
        userApplyPO.setFriendId(fromId);
        userApplyPO.setUserId(uid);
        userApplyPO.setIsDeal(false);
        BaseUserApplyPO obj = userApplyMapper.selectOne(userApplyPO);
        if (StringHandler.isNotEmpty(obj)) {
            obj.setIsDeal(true);
            obj.setUpdateTime(LocalDateTime.now());
            int result = userApplyMapper.updateByPrimaryKeySelective(obj);
            if (result > 0) {
                //申请通过之后
                String jsonStr = (String) Redis.hash.hGet(UserKey.getUserApplyKey(uid),
                        fromId);
                if (StringHandler.isNotEmpty(jsonStr)) {
                    BaseUserApplyPO cache = JSONObject.parseObject(jsonStr, BaseUserApplyPO.class);
                    cache.setIsDeal(true);
                    Redis.hash.hSet(UserKey.getUserApplyKey(uid), fromId, JsonUtil.toJson(cache));
                }
                //双向绑定用户好友信息
                List<BaseUserFriendsPO> list = new ArrayList<>();
                BaseUserFriendsPO currentObj = new BaseUserFriendsPO();
                currentObj.setUserId(uid);
                currentObj.setFriendId(fromId);
                currentObj.setCreateTime(LocalDateTime.now());
                currentObj.setStatus(true);
                currentObj.setApplyId(obj.getId());
                currentObj.setDisturb(false);
                list.add(currentObj);
                BaseUserFriendsPO fromObj = new BaseUserFriendsPO();
                fromObj.setUserId(fromId);
                fromObj.setFriendId(uid);
                fromObj.setCreateTime(LocalDateTime.now());
                fromObj.setStatus(true);
                fromObj.setApplyId(obj.getId());
                fromObj.setDisturb(false);
                list.add(fromObj);
                int i = userFriendsMapper.insertList(list);
                if (i == 2) {
                    //好友信息添加进缓存
                    this.saveCache(currentObj);
                    this.saveCache(fromObj);

                    //发送消息
                    MessageResponseBean messageResponseBean = UserUtils.getMessageResponse(uid, null, EnumType.MessageCode.MESSAGE_USER_AGREE.getCode(), null, DateUtil.getDate(new Date(), BaseConstants.BASE_FORMAT), 0.0, 0.0);
                    GroupUtils.sendIfAbsent(messageResponseBean, fromId, null);
                    return i;
                } else {
                    SystemError.wrapBs("500", "操作失败");
                }
            } else {
                SystemError.wrapBs("500", "操作失败");
            }
        }
        return 0;
    }

    @Override
    public List<BaseUserApplyPO> getApplyList(String uid) {
        String key = UserKey.getUserApplyKey(uid);
        List<BaseUserApplyPO> list = null;
        if (Redis.key.exists(key)) {
            Map result = Redis.hash.hgetall(key);
            if (result != null && !result.isEmpty()) {
                List<String> arrayList = new ArrayList<String>(result.values());
                if (StringHandler.isNotEmpty(arrayList)) {
                    Redis.key.setKeyTimeout(key, BaseConstants.FriendsConstants.SAVE_TIME_APPLY);
                    list = arrayList
                            .stream()
                            .map(s -> {
                                BaseUserApplyPO obj = JSONObject.parseObject(s, BaseUserApplyPO.class);
                                obj.setFriendId(McodeHandler.to32Radix(Long.parseLong(obj.getFriendId())));
                                obj.setUserId(McodeHandler.to32Radix(Long.parseLong(obj.getUserId())));
                                return obj;

                            })
                            .collect(Collectors.toList());
                    //重新排序
                    try {
                        Collections.sort(list, new Comparator<BaseUserApplyPO>() {
                            @Override
                            public int compare(BaseUserApplyPO o1, BaseUserApplyPO o2) {
                                return StringHandler.getInt(o2.getId()-o1.getId());
                            }
                        });
                    }catch (Exception e){
                        log.error("用户:【"+uid+"】获取申请列表排序错误",e);
                    }
                    return list;
                }
            }
        }
        list = userApplyMapper.getApplyList(uid);
        if (StringHandler.isNotEmpty(list)) {
            //保存缓存
            Map<String, String> collect = list
                    .stream()
                    .collect(Collectors.toMap(BaseUserApplyPO::getFriendId, JsonUtil::toJson));
            Redis.hash.hmset(key, collect);
            Redis.key.setKeyTimeout(key, BaseConstants.FriendsConstants.SAVE_TIME_APPLY);
            list.forEach(o -> {
                o.setFriendId(McodeHandler.to32Radix(Long.parseLong(o.getFriendId())));
                o.setUserId(McodeHandler.to32Radix(Long.parseLong(o.getUserId())));
            });
            return list;
        }
        return list;
    }

    /**
     * 存缓存
     */
    private void saveCache(BaseUserFriendsPO baseUserFriendsPO) {
        BaseUserFriendsPO currentInfo = userFriendsMapper.getFriendsDetailByUserId(baseUserFriendsPO.getUserId(), baseUserFriendsPO.getFriendId());
        Redis.hash.hSet(UserKey.getUserFriendsListKey(currentInfo.getUserId()), String.valueOf(currentInfo.getFriendId()), JsonUtil.toJson(currentInfo));
        //删除没有好友列表的标志
        if (StringHandler.isNotEmpty(Redis.str.get(UserKey.getNoListFlag(currentInfo.getUserId())))) {
            Redis.key.del(UserKey.getNoListFlag(currentInfo.getUserId()));
        }
    }

    @Override
    public void friendBlack(String uid, long friendId, int type) {
        if (friendId == 0 || uid.equals(StringHandler.getString(friendId))) {
            SystemError.wrapBs("500", "操作失败");
        }
        try {
            int i = userFriendsMapper.friendBlack(uid, friendId, type);
            if (i == 0) {
                SystemError.wrapBs("500", "操作失败");
            }
            if (type == 1) {
                FriendsManager.addBlackFriends(uid, friendId);
            } else {
                FriendsManager.removeBlackFriends(uid, friendId);
            }
        }catch (Exception e){
            log.error("拉黑操作失败",e);
            SystemError.wrapBs("500", "操作失败");
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setDisturb(Long uid, String friendId, String groupId) {
        int row = 0;
        //friendId 不为空  就修改好友信息
        if (StringHandler.isNotEmpty(friendId)) {
            BaseUserFriendsPO baseUserFriendsPO = new BaseUserFriendsPO();
            baseUserFriendsPO.setUserId(String.valueOf(uid));
            baseUserFriendsPO.setFriendId(String.valueOf(McodeHandler.from32Radix(friendId)));
            baseUserFriendsPO.setStatus(true);
            BaseUserFriendsPO result = userFriendsMapper.selectOne(baseUserFriendsPO);
            if (StringHandler.isEmpty(result)) {
                SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "数据出错");
            }
            result.setDisturb(!result.getDisturb());
            row = userFriendsMapper.updateByPrimaryKeySelective(result);
            if (row > 0) {
                //修改好有缓存信息
                if (Redis.key.exists(UserKey.getUserFriendsListKey(uid))) {
                    String o = (String) Redis.hash.hGet(UserKey.getUserFriendsListKey(uid), String.valueOf(McodeHandler.from32Radix(friendId)));
                    BaseUserFriendsPO jsonObj = JsonUtil.jsonToBean(o, BaseUserFriendsPO.class);
                    jsonObj.setDisturb(result.getDisturb());
                    Redis.hash.hSet(UserKey.getUserFriendsListKey(uid), String.valueOf(McodeHandler.from32Radix(friendId)), JsonUtil.toJson(jsonObj));
                }
            }
        }

        //groupId 不为空  就修群的信息
        if (StringHandler.isNotEmpty(groupId)) {
            BaseUserGroupPO baseUserGroupPO = new BaseUserGroupPO();
            baseUserGroupPO.setUserId(String.valueOf(uid));
            baseUserGroupPO.setGroupId(Long.valueOf(groupId));
            baseUserGroupPO.setStatus(1);
            baseUserGroupPO.setAuditStatus(1);
            BaseUserGroupPO result = userGroupMapper.selectOne(baseUserGroupPO);
            if (StringHandler.isEmpty(result)) {
                SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "数据出错");
            }
            result.setDisturb(!result.getDisturb());
            row = userGroupMapper.updateByPrimaryKeySelective(result);
            if (row > 0) {
                //修改好有缓存信息
                if (Redis.key.exists(UserKey.groupInfoKey(uid))) {
                    String o = (String) Redis.hash.hGet(UserKey.groupInfoKey(uid), groupId);
                    BaseGroupInfoPO jsonObj = JsonUtil.jsonToBean(o, BaseGroupInfoPO.class);
                    jsonObj.setDisturb(result.getDisturb());
                    Redis.hash.hSet(UserKey.groupInfoKey(uid), groupId, JsonUtil.toJson(jsonObj));
                }
            }
        }

        //如果说操作数据为0 修是修改失败
        if (row <= 0) {
            SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "操作失败");
        }
    }


    @Override
    public int delApplyById(String uid, String applyId) {
        BaseUserApplyPO baseUserApplyPo = userApplyMapper.selectByPrimaryKey(applyId);
        //如果说是申请人自己删除的好友  则不保留申请记录
        //如果说是接受人删除   设置请求为未处理
        if (baseUserApplyPo != null) {
            int row = userApplyMapper.delete(baseUserApplyPo);
            //删除缓存
            Redis.hash.delHash(UserKey.getUserApplyKey(baseUserApplyPo.getUserId()),
                    baseUserApplyPo.getFriendId());
            return row;
        } else {
            return 0;
        }
    }

    @Override
    public boolean groupManager(String uid) {
        if(userFriendsMapper.groupManager(uid)>0){
            return true;
        }
        return false;
    }

    @Override
    public int userFriendNumber(String uid) {
        return userFriendsMapper.userFriendNumber(uid);
    }

    @Override
    public int userApplyNumber(String uid) {
        return userFriendsMapper.userApplyNumber(uid);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void copyFriends(String uid, long friendsId) {
        DynamicDataSourceContextHolder.setDataSourceKey("ysIm");
        //判断用户是否有好友（排除当前好友）
        int frirnds = userFriendsMapper.friendsCount(friendsId,StringHandler.getLong(uid));
        if(frirnds>0){
            SystemError.wrapBs("500", "复制错误，该好友不满足条件");
        }
        //复制用户好友
        userFriendsMapper.copyUserFriend(StringHandler.getLong(uid),friendsId);
        //复制用户被添加好友
        userFriendsMapper.copyFriendUser(StringHandler.getLong(uid),friendsId);
        //好友信息添加进缓存
        List<BaseUserFriendsPO> list = userFriendsMapper.getFriendsListByUserId(friendsId+"");
        for (BaseUserFriendsPO baseUserFriendsPO : list) {
            this.saveCache(baseUserFriendsPO);
        }
        List<BaseUserFriendsPO> friendsListByUserId = userFriendsMapper.getFriendsByUserId(friendsId);
        for (BaseUserFriendsPO baseFriendsUserPO : friendsListByUserId) {
            this.saveCache(baseFriendsUserPO);
        }
    }
}
